
//
//  HttpClient.m
//  AFNTest
//
//  Created by hebidu on 15/7/9.
//  Copyright (c) 2015年 Boye. All rights reserved.
//

#import "BoyeHttpClient.h"
#import "AFNetworking.h"
#import "AFURLSessionManager.h"

// token
#import "BoyeToken.h"

// 加解密
#import "ZKCryptionHandle.h"



@interface BoyeHttpClient()

@end


@implementation BoyeHttpClient

+ (void) cancelAllOperations{
    
    [[AFHTTPRequestOperationManager manager].operationQueue cancelAllOperations];
}

+ (void)stopMonitorNetwork{
    
    [[AFNetworkReachabilityManager sharedManager] stopMonitoring];
    
}
+ (void)startMonitorNetwork{
            
    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
}

- (BOOL)getNetworkStatus{
    
    return [[AFNetworkReachabilityManager sharedManager] isReachable];
}




/**
 *  post请求
 *
 *  @param type    请求类型（什么请求，登录？注册？。。。）
 *  @param params  明文参数（账号，密码等）内部进行加密
 *  @param success result：解密后的数据（一般为字典）
 *  @param failure
 */
+ (void)post:(NSString *)type
   apiVerson:(NSInteger)ver
      params:(NSDictionary *)params
     success:(void(^)(AFHTTPRequestOperation *operation, id result))success
     failure:(void(^)(AFHTTPRequestOperation *operation, NSError *error))failure {
    
            
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    // 默认超时时间10秒
    manager.requestSerializer.timeoutInterval = 15;
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];
    
    // 加密
    NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
    
    NSDate *date = [NSDate date];
    NSTimeInterval time = [date timeIntervalSince1970];
    [dic setValue:@((int)time) forKey:@"time"]; // 时间戳参数
    
    [dic setValue:@"111" forKey:@"notify_id"]; //
    
    // 如果没有业务参数（params == nil），data参数传入空的字符串
    NSString *dataStr;
    if (params == nil) {
        dataStr = @"";
    } else {
        dataStr = [ZKCryptionHandle encryptString:params]; // 明文参数加密
    }
    
    [dic setValue:dataStr forKey:@"data"]; // 加密后的数据参数
    [dic setValue:type forKey:@"type"]; // 请求类型参数
    [dic setValue:@"md5" forKey:@"alg"]; // 加密方式
    [dic setValue:@(ver) forKey:@"api_ver"]; // 版本号，和服务器一样才能返回正确数据
    NSString *version = [NSString stringWithFormat:@"%@.%@", kCurrentVersion, kCurrentBuild];
    NSArray *numAry = [version componentsSeparatedByString:@"."];
    NSInteger versionNum = [numAry[0] integerValue] * 10000 + [numAry[1] integerValue] * 100 + [numAry[2] integerValue];
    [dic setValue:@(versionNum) forKey:@"app_version"]; // 版本号
    [dic setValue:@"ios" forKey:@"app_type"]; // 版本号

    NSString *signStr = [ZKCryptionHandle signData:dic];
    [dic setValue:signStr forKey:@"sign"]; // 签名
    
    // 请求的url，所有请求都用一个url（除了请求token的以外）
    NSString *urlStr = [BOYE_API_URL stringByAppendingFormat:@"?access_token=%@", BOYE_CLIENT_ID];
    
    [manager POST:urlStr
       parameters:dic
          success:^(AFHTTPRequestOperation *operation ,id responseObject){
              
              @try{
              
              
              if ([responseObject isKindOfClass:[NSDictionary class]]) {
                  NSDictionary *responseDic = (NSDictionary *)responseObject;
                  NSString *dataStr = responseDic[@"data"]; // 返回的加密的数据字符串
                  NSDictionary *dataDic = [ZKCryptionHandle decryptString:dataStr]; // 解密后的字典
                  NSString *code = [dataDic valueForKey:@"code"]; // 数据码
                  id data = [dataDic valueForKey:@"data"]; // 数据
                  
                  NSLog(@"%@请求结果_code:%@", type, code);
                  
                  if ([code intValue] == 0 && ![code isKindOfClass:[NSNull class]]) { // 返回正常无误
                      if (success) {
                          success(operation, data); // 返回的可能是字典，也可能是字符串
                      }
                  } else if ([code intValue] == 401 && [data isKindOfClass:[NSString class]]) {
                      [BoyeToken clearAccessToken];
                      if (failure) {
                          failure(operation,[[NSError alloc] initWithDomain:@"请重试" code:401 userInfo:nil]);
                      }
                      return ;
                  } else { // code 返回字符串 和 code值
//                              [SVProgressHUD showErrorWithStatus:(NSString *)data withDuration:3.f];
                      if (failure) {
                          NSLog(@"data:%@", data);
                          NSError * error = nil;
                          if([data isKindOfClass:[NSString class]]){
                              error = [[NSError alloc] initWithDomain:data code:[code intValue] userInfo:nil];
                          }else{
                              error = [[NSError alloc] initWithDomain:@"未知错误!请重试" code:[code intValue] userInfo:nil];
                          }
                          failure(operation,error);
                      }
                  }
              }
                  
                  
              }@catch (NSException * e) {
                  NSLog(@"Exception: %@", e);
                  UIAlertView * alert =
                  [[UIAlertView alloc]
                   initWithTitle:@"发生异常,请重试"
                   message: [[NSString alloc] initWithFormat:@"%@",e]
                   delegate:nil
                   cancelButtonTitle:nil
                   otherButtonTitles:@"OK", nil];
                  [alert show];
                  
              }
                  
                  
          } failure:^(AFHTTPRequestOperation *operation , NSError *error){

              if (failure) {
            
                  if ([CommonCache isNetworkOff]) {
                      failure(operation, [NSError errorWithDomain:@"您没有连接网络!" code:-1 userInfo:nil]);
                  } else {
                      if (error.code == NSURLErrorTimedOut) {
                          [SVProgressHUD showErrorWithStatus:@"请求超时!" withDuration:3];
                          return ;
                      }
                      if(error.code == NSURLErrorBadURL){
                          [SVProgressHUD showErrorWithStatus:@"非法请求地址!" withDuration:3];
                          return ;
                      }
                      if(error.code == NSURLErrorCannotFindHost){
                          [SVProgressHUD showErrorWithStatus:@"无法查找远程主机!" withDuration:3];
                          return ;
                      }
                      
                      if(error.code == NSURLErrorCannotConnectToHost){
                          [SVProgressHUD showErrorWithStatus:@"远程主机无法连接!" withDuration:3];
                          return ;
                          
                      }
                      if([error.domain  isEqualToString: @"NSCocoaErrorDomain"]){
                          [SVProgressHUD showErrorWithStatus:error.localizedDescription withDuration:3];
                          return ;
                      }
                      
                      if([error.domain isEqualToString: @"NSURLErrorDomain"]){
                          [SVProgressHUD showErrorWithStatus:@"请求失败!" withDuration:3];
                          return ;
                      }
                      
                      failure(operation, error);
                  }
              }
          }];

}




/**
 *  图片上传
 *
 *  @param image    图片
 *  @param type     类型(avatar=头像,gallery=相册,other=其它,ID=身份证)
 *  @param success  成功后，返回图片的网络地址
 *  @param failure  失败
 */
+ (void)uploadImage:(UIImage *)image
              type:(NSString *)type
           success:(void (^)(NSDictionary *))success
           failure:(void(^)(AFHTTPRequestOperation *operation, NSError *error))failure {
    // 获取token
    
    [BoyeToken isTokenEffectiveComplete:^(NSString *token) {
        if (token) {
            // manager对象
            AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
            manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];
            
            // 构造网址
            NSString *url = [NSString stringWithFormat:@"%@/File/upload?client_id=%@",BOYE_API_URL, BOYE_CLIENT_ID];
            
            // 处理图片
            NSData * data = UIImageJPEGRepresentation(image, 0.5);    //@"file://path/to/image.png"    //@"file://path/to/image.png"
            
            // 构造请求参数
            UserModel *user = [CommonCache getUserInfo];
            NSDictionary *params = @{@"uid":user.uid,
                                     @"type":type,
                                     @"image":data};
        
            [SVProgressHUD showWithStatus:@"正在提交图片..." maskType:SVProgressHUDMaskTypeClear];
            
            // 发送请求
            [manager
             POST:url
             parameters:params
             constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
                 
                 [formData appendPartWithFileData:data name:@"image" fileName:@"xxx.jpg" mimeType:@""];
                 
             } success:^(AFHTTPRequestOperation * _Nonnull operation, id  _Nonnull responseObject) {
                 
                 NSLog(@"responseObject = %@", responseObject);
                 
                 if ([responseObject[@"code"] integerValue] == 0) {
                     // 获取返回的图片URL
                     NSDictionary *responseDic = responseObject;
                     NSDictionary *dataDic = responseDic[@"data"];
                     if (success) {
                         success(dataDic);
                     }
                     [SVProgressHUD showSuccessWithStatus:@"上传成功！" withDuration:1.5];
                 } else {
                     if (failure) {
                         failure(operation, [NSError errorWithDomain:@"上传失败" code:-1 userInfo:nil]);
                     }
                     [SVProgressHUD showErrorWithStatus:@"图片上传失败！" withDuration:1.5];

                 }
                 
                 
             } failure:^(AFHTTPRequestOperation * _Nonnull operation, NSError * _Nonnull error) {
                 
                 if (failure) {
                     failure(operation, error);
                 }
                 [SVProgressHUD showErrorWithStatus:@"图片上传失败！" withDuration:1.5];
             }];

        }
    }];
}




#pragma  mark- 获得完整的ULR --
+ (NSString *)getFullURLString:(NSString *)urlstr{

    NSString *base_url = BOYE_API_URL;
    
    NSString *  url = [base_url stringByAppendingString:urlstr];
    url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    return url;
}

+ (void)clearAccessToken{
    
}








#pragma mark - AFNetWorking 3.0 测试
/**
 *  post请求
 *
 *  @param type    请求类型（什么请求，登录？注册？。。。）
 *  @param params  明文参数（账号，密码等）内部进行加密
 *  @param success result：解密后的数据（一般为字典）
 *  @param failure
 */
+ (void)sessionPost:(NSString *)type
          apiVerson:(NSInteger)ver
             params:(NSDictionary *)params
            success:(void(^)(NSURLSessionDataTask *task, id result))success
            failure:(void(^)(NSURLSessionDataTask *task, NSError *error))failure {
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    // 默认超时时间10秒
    manager.requestSerializer.timeoutInterval = 10;
    // AFN序列化，接收内容类型为以下这些
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];
    
    // 加密
    NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
    
    NSDate *date = [NSDate date];
    NSTimeInterval time = [date timeIntervalSince1970];
    [dic setValue:@((int)time) forKey:@"time"]; // 时间戳参数
    
    [dic setValue:@"111" forKey:@"notify_id"]; //
    
    // 如果没有业务参数（params == nil），data参数传入空的字符串
    NSString *dataStr;
    if (params == nil) {
        dataStr = @"";
    } else {
        dataStr = [ZKCryptionHandle encryptString:params]; // 明文参数加密
    }
    
    [dic setValue:dataStr forKey:@"data"];                  // 加密后的数据参数
    [dic setValue:type forKey:@"type"];                     // 请求类型参数
    [dic setValue:@"md5" forKey:@"alg"];                    // 加密方式
    [dic setValue:@(ver) forKey:@"api_ver"];                // 版本号，和服务器一样才能返回正确数据
    NSString *signStr = [ZKCryptionHandle signData:dic];    // 获得加密签名
    [dic setValue:signStr forKey:@"sign"];                  // 签名
    
    // 请求的url，所有请求都用一个url（除了请求token的以外）
    NSString *urlStr = [BOYE_API_URL stringByAppendingFormat:@"?access_token=%@", BOYE_CLIENT_ID];
    
    [manager POST:urlStr
       parameters:dic
          success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
        
        if ([responseObject isKindOfClass:[NSDictionary class]]) {
            
              NSDictionary *responseDic = (NSDictionary *)responseObject;
              NSString *dataStr = responseDic[@"data"]; // 返回的加密的数据字符串
              NSDictionary *dataDic = [ZKCryptionHandle decryptString:dataStr]; // 解密后的字典
              NSString *code = [dataDic valueForKey:@"code"]; // 数据码
              id data = [dataDic valueForKey:@"data"]; // 数据

              NSLog(@"%@请求结果_code:%@", type, code);

              if ([code intValue] == 0) { // 返回正常无误
                  if (success) {
                      success(task, data); // 返回的可能是字典，也可能是字符串
                  }
              }
              else if ([code intValue] == 401 && [data isKindOfClass:[NSString class]]) {
                  if (failure) {
                      failure(task, [[NSError alloc] initWithDomain:@"请重试" code:401 userInfo:nil]);
                  }
                  return ;
              }
              else {
                  if (failure) {
                      failure(task, [[NSError alloc] initWithDomain:(NSString *)data code:[code intValue] userInfo:nil]);
                  }
              }
          }
    } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {
        
        if (failure) {
            failure(task, error);
        }
    }];
}

/**
 *  图片上传
 *
 *  @param image    图片
 *  @param type     类型(avatar=头像,gallery=相册,other=其它,ID=身份证)
 *  @param success  成功后，返回图片的网络地址
 *  @param failure  失败
 */
+ (void)sessionUploadImage:(UIImage *)image
                      type:(NSString *)type
                   success:(void(^)(NSDictionary *))success
                   failure:(void(^)(NSURLSessionDataTask *operation, NSError *error))failure {
    // 获取token
    
    [BoyeToken isTokenEffectiveComplete:^(NSString *token) {
        if (token) {
            // manager对象
            AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
            // AFN序列化，接收内容类型为以下这些
            manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];
            
            // 构造网址
            NSString *url = [NSString stringWithFormat:@"%@/File/upload?client_id=%@",BOYE_API_URL, BOYE_CLIENT_ID];
            
            // 处理图片
            NSData *data = UIImageJPEGRepresentation(image, 0.5);
            
            // 构造请求参数
            UserModel *user = [CommonCache getUserInfo];
            NSDictionary *params = @{@"uid":user.uid,
                                     @"type":type,
                                     @"image":data};
            
            [SVProgressHUD showWithStatus:@"正在提交图片..." maskType:SVProgressHUDMaskTypeClear];
            
            [manager POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
                
                [formData appendPartWithFileData:data name:@"image" fileName:@"xxx.jpg" mimeType:@""];

            } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
                
                NSLog(@"responseObject = %@", responseObject);
                
                // 获取返回的图片URL
                NSDictionary *responseDic = responseObject;
                NSDictionary *dataDic = responseDic[@"data"];
                if (success) {
                    success(dataDic);
                }
                [SVProgressHUD showSuccessWithStatus:@"上传成功！" withDuration:1.5];
                
            } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {
                
                if (failure) {
                    failure(task, error);
                }
                [SVProgressHUD showErrorWithStatus:@"图片上传失败！" withDuration:1.5];
            }];
        }
    }];
}

@end
